home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 …ember: Reference Library / Dev.CD Dec 97 RL.toast / What's New / Tool Chest / Testing & Debugging / Virtual User / Examples / External Tool Templates / CPlus Tool Template / PascalString.cp < prev    next >
Encoding:
Text File  |  1997-10-15  |  19.7 KB  |  693 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // PascalString.cp 
  3. // Copyright © 1985-1992 by Apple Computer, Inc.  All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6.  
  7. #include "PascalString.h"
  8.  
  9. #ifndef __STDIO__
  10. #include <StdIo.h>
  11. #endif
  12.  
  13. #ifndef __STRING__
  14. #include <String.h>
  15. #endif
  16.  
  17.  
  18. #pragma segment Main
  19.  
  20.  
  21. //----------------------------------------------------------------------------------------
  22. // Inline friend function definitions for relational string operators.
  23. //----------------------------------------------------------------------------------------
  24.  
  25. Boolean operator==(const CString& s1, const char* s2)
  26. {
  27.     return RelString(s1, CStr255(s2), false, true) == 0;
  28. }
  29.  
  30. Boolean operator==(const char* s1, const CString& s2)
  31. {
  32.     return RelString(CStr255(s1), s2, false, true) == 0;
  33. }
  34.  
  35. Boolean operator==(const CString& s1, const CString& s2)
  36. {
  37.     return RelString(s1, s2, false, true) == 0;
  38. }
  39.  
  40. Boolean operator!=(const CString& s1, const char* s2)
  41. {
  42.     return RelString(s1, CStr255(s2), false, true) != 0;
  43. }
  44.  
  45. Boolean operator!=(const char* s1, const CString& s2)
  46. {
  47.     return RelString(CStr255(s1), s2, false, true) != 0;
  48. }
  49.  
  50. Boolean operator!=(const CString& s1, const CString& s2)
  51. {
  52.     return RelString(s1, s2, false, true) != 0;
  53. }
  54.  
  55. Boolean operator>(const CString& s1, const char* s2)
  56. {
  57.     return RelString(s1, CStr255(s2), false, true) > 0;
  58. }
  59.  
  60. Boolean operator>(const char* s1, const CString& s2)
  61. {
  62.     return RelString(CStr255(s1), s2, false, true) > 0;
  63. }
  64.  
  65. Boolean operator>(const CString& s1, const CString& s2)
  66. {
  67.     return RelString(s1, s2, false, true) > 0;
  68. }
  69.  
  70. Boolean operator<(const CString& s1, const char* s2)
  71. {
  72.     return RelString(s1, CStr255(s2), false, true) < 0;
  73. }
  74.  
  75. Boolean operator<(const char* s1, const CString& s2)
  76. {
  77.     return RelString(CStr255(s1), s2, false, true) < 0;
  78. }
  79.  
  80. Boolean operator<(const CString& s1, const CString& s2)
  81. {
  82.     return RelString(s1, s2, false, true) < 0;
  83. }
  84.  
  85. Boolean operator>=(const CString& s1, const char* s2)
  86. {
  87.     return RelString(s1, CStr255(s2), false, true) >= 0;
  88. }
  89.  
  90. Boolean operator>=(const char* s1, const CString& s2)
  91. {
  92.     return RelString(CStr255(s1), s2, false, true) >= 0;
  93. }
  94.  
  95. Boolean operator>=(const CString& s1, const CString& s2)
  96. {
  97.     return RelString(s1, s2, false, true) >= 0;
  98. }
  99.  
  100. Boolean operator<=(const CString& s1, const char* s2)
  101. {
  102.     return RelString(s1, CStr255(s2), false, true) <= 0;
  103. }
  104.  
  105. Boolean operator<=(const char* s1, const CString& s2)
  106. {
  107.     return RelString(CStr255(s1), s2, false, true) <= 0;
  108. }
  109.  
  110. Boolean operator<=(const CString& s1, const CString& s2)
  111. {
  112.     return RelString(s1, s2, false, true) <= 0;
  113. }
  114.  
  115. //========================================================================================
  116. // CLASS CString
  117. //========================================================================================
  118.  
  119.  
  120. //----------------------------------------------------------------------------------------
  121. // CString::InsertHelper(CString):
  122. //----------------------------------------------------------------------------------------
  123.  
  124. void CString::InsertHelper(const CString& insStr,
  125.                           short pos,
  126.                           short maxLength)
  127. {
  128.     if (pos > Length() + 1)
  129.     {
  130. #if qDebugMsg
  131.         fprintf(stderr, "###CString::InsertHelper: Insert position greater than length of CString.\n");
  132. #endif
  133.         if (Length() < maxLength)    
  134.             pos = Length() + 1;
  135.     }
  136.     
  137. #if qDebugMsg
  138.     if (Length() + insStr.Length() > maxLength)
  139.         fprintf(stderr, "### CString::InsertHelper: CString truncated during insert call.\n");    
  140. #endif
  141.  
  142.     short usableLengthOfInsertString;
  143.     short endPosOfInsertString;
  144.     short usableLengthOfShiftedString;
  145.     
  146.     if (pos + insStr.Length() > maxLength)
  147.         usableLengthOfInsertString = maxLength - pos + 1;
  148.     else
  149.         usableLengthOfInsertString = insStr.Length();
  150.     endPosOfInsertString = pos + usableLengthOfInsertString - 1;
  151.     
  152.     if ((endPosOfInsertString + 1) + (Length() - pos + 1) > maxLength)
  153.         usableLengthOfShiftedString = maxLength - endPosOfInsertString;
  154.     else
  155.         usableLengthOfShiftedString = Length() - pos + 1;
  156.         
  157.     memmove(&fStr[endPosOfInsertString + 1], &fStr[pos], usableLengthOfShiftedString);
  158.     memmove(&fStr[pos], &insStr.fStr[1], usableLengthOfInsertString);
  159.     Length() = usableLengthOfShiftedString + endPosOfInsertString;
  160. } // CString::InsertHelper(CString)
  161.  
  162.  
  163. //----------------------------------------------------------------------------------------
  164. // CString::InsertHelper(char*):
  165. //----------------------------------------------------------------------------------------
  166.  
  167. void CString::InsertHelper(const char* insStr,
  168.                           short pos,
  169.                           short maxLength)
  170. {
  171.     this->InsertHelper(CStr255(insStr), pos, maxLength);
  172. } // CString::InsertHelper(char*)
  173.  
  174.  
  175. //----------------------------------------------------------------------------------------
  176. // CString::operator[]: !!! we'd ideally like this method to be inlined but CFront doesn't
  177. // seem to want to inline it for us !!!
  178. //----------------------------------------------------------------------------------------
  179.  
  180. unsigned char& CString::operator[](short pos)
  181. {
  182.     return fStr[pos];
  183. } // CString::operator[] for non-const CString
  184.  
  185.  
  186. //----------------------------------------------------------------------------------------
  187. // CString::operator char*:
  188. //----------------------------------------------------------------------------------------
  189.  
  190. CString::operator char*() const
  191. {
  192.     const short kTempCStrings = 4;
  193.     static short currentCString = 0;
  194.     static char cStrings[kTempCStrings][kStr255Len+1];
  195.     
  196.     currentCString = (currentCString + 1) % kTempCStrings;
  197.     
  198.     strncpy(cStrings[currentCString], (char *) &fStr[1], Length());
  199.     cStrings[currentCString][Length()] = '\0';
  200.     
  201.     return cStrings[currentCString];
  202. } // CString::operator char*
  203.  
  204.  
  205. //----------------------------------------------------------------------------------------
  206. // CString::operator long:
  207. //----------------------------------------------------------------------------------------
  208.  
  209. CString::operator long() const
  210. {
  211.     // The following statement looks like it should work. Right?
  212.     //
  213.     //    return *((long *) &fStr[1]);
  214.     //
  215.     // Wrong, the C compiler generates a MOVE.L starting on a odd byte boundary for the
  216.     // preceding statement. This is illegal on the 68000. But its _NOT_ a bug, because
  217.     // according to the ANSI C reference manual, "A pointer to one type may be converted
  218.     // to a pointer to another type. The resulting pointer may cause an addressing
  219.     // exception if the subject pointer does not refer to an object suitably aligned in
  220.     // storage".
  221.     
  222.     long returnLong;
  223.     
  224.     memcpy(&returnLong, &fStr[1], sizeof(long));
  225.     return returnLong;
  226. } // CString::operator long
  227.  
  228.  
  229. //----------------------------------------------------------------------------------------
  230. // CString::Pos(char*):
  231. //----------------------------------------------------------------------------------------
  232.  
  233. unsigned char CString::Pos(const char* subStr, unsigned char startPos)
  234. {
  235.     char cStr[kStr255Len + 1];
  236.     char* ptr;
  237.     
  238.     memcpy(cStr, &fStr[1], Length());
  239.     cStr[Length()] = 0;
  240.     ptr = strstr(&cStr[startPos - 1], subStr);
  241.     return ptr != NULL ? (ptr - cStr) + 1 : 0;
  242. } // CString::Pos(char*)
  243.  
  244.  
  245. //----------------------------------------------------------------------------------------
  246. // CString::Pos(CString):
  247. //----------------------------------------------------------------------------------------
  248.  
  249. unsigned char CString::Pos(const CString& subStr, unsigned char startPos)
  250. {
  251.     char cStr[kStr255Len + 1];
  252.  
  253.     memcpy(cStr, &subStr.fStr[1], subStr.Length());
  254.     cStr[subStr.Length()] = 0;
  255.     return this->Pos(cStr, startPos);
  256. } // CString::Pos(CString)
  257.  
  258.  
  259.  
  260. //========================================================================================
  261. // CLASS CStr255
  262. //========================================================================================
  263.  
  264.  
  265. //----------------------------------------------------------------------------------------
  266. // CStr255::CStr255(char*):
  267. //----------------------------------------------------------------------------------------
  268.  
  269. CStr255::CStr255(const char* str)
  270. {
  271.     // Truncate the C CString to 255 bytes if necessary.
  272.  
  273.     Length() = str == NULL ? 0 : strlen(str);
  274.     
  275.     if (Length() > kStr255Len)
  276.         Length() = kStr255Len;
  277.     memcpy(&fStr[1], str, Length());
  278. } // CStr255::CStr255(char*)
  279.  
  280.  
  281. //----------------------------------------------------------------------------------------
  282. // CStr255::CStr255(long): Useful for converting OSType's into CStr255's.
  283. //----------------------------------------------------------------------------------------
  284.  
  285. CStr255::CStr255(const long id)
  286. {
  287.     Length() = 4;
  288.     memcpy(&fStr[1], &id, Length());
  289. } // CStr255::CStr255(long)
  290.  
  291.  
  292. //----------------------------------------------------------------------------------------
  293. // CStr255::Copy:
  294. //----------------------------------------------------------------------------------------
  295.  
  296. CStr255 CStr255::Copy(short pos, short length)
  297. {
  298.     CStr255 newString;
  299.     
  300.     length = length > Length() - pos + kLengthByte ? Length() - pos + kLengthByte : length;
  301.     
  302.     if (length > 0)
  303.     {
  304.         memcpy(&newString.fStr[1], &fStr[pos], length);
  305.         newString.Length() = length;
  306.     }
  307.     else
  308.         newString = "";
  309.         
  310.     return newString;
  311.     
  312. } // CStr255::Copy
  313.  
  314.  
  315. //----------------------------------------------------------------------------------------
  316. // CStr255::operator+:
  317. //----------------------------------------------------------------------------------------
  318.  
  319. CStr255 operator+(const CString& s1,
  320.                   const char* s2)
  321. {
  322.     CStr255 newStr;
  323.     short s2Len = s2 == NULL ? 0 : strlen((const char *) s2);
  324.  
  325.     if (s1.Length() + s2Len > kStr255Len)
  326.         newStr.Length() = kStr255Len;
  327.     else
  328.         newStr.Length() = s1.Length() + s2Len;
  329.         
  330.     memcpy(&newStr.fStr[1], &s1.fStr[1], s1.Length());
  331.     memcpy(&newStr.fStr[s1.Length() + kLengthByte], s2, newStr.Length() - s1.Length());
  332.  
  333.     return newStr;
  334. } // CStr255::operator+
  335.  
  336.  
  337. //----------------------------------------------------------------------------------------
  338. // CStr255::operator+(char*,CString):
  339. //----------------------------------------------------------------------------------------
  340.  
  341. CStr255 operator+(const char* s1,
  342.                   const CString& s2)
  343. {
  344.     CStr255 newStr;
  345.     short s1Len = s1 == NULL ? 0 : strlen((const char *) s1);
  346.  
  347.     if (s1Len + s2.Length() > kStr255Len)
  348.         newStr.Length() = kStr255Len;
  349.     else
  350.         newStr.Length() = s1Len + s2.Length();
  351.         
  352.     memcpy(&newStr.fStr[1], s1, s1Len);
  353.     memcpy(&newStr.fStr[s1Len + kLengthByte], s2.fStr + 1, newStr.Length() - s1Len);
  354.  
  355.     return newStr;
  356. } // CStr255::operator+(char*,CString)
  357.  
  358.  
  359. //----------------------------------------------------------------------------------------
  360. // CStr255::operator+(CString,CString):
  361. //----------------------------------------------------------------------------------------
  362.  
  363. CStr255 operator+(const CString& s1,
  364.                   const CString& s2)
  365. {
  366.     CStr255 newStr;
  367.  
  368.     if (s1.Length() + s2.Length() > kStr255Len)
  369.         newStr.Length() = kStr255Len;
  370.     else
  371.         newStr.Length() = s1.Length() + s2.Length();
  372.         
  373.     memcpy(&newStr.fStr[1], &s1.fStr[1], s1.Length());
  374.     memcpy(&newStr.fStr[s1.Length() + kLengthByte], s2.fStr + 1, newStr.Length() - s1.Length());
  375.  
  376.     return newStr;
  377. } // CStr255::operator+(CString,CString)
  378.  
  379.  
  380. //----------------------------------------------------------------------------------------
  381. // CStr255::operator +=(CString):  Concatinate a string
  382. //----------------------------------------------------------------------------------------
  383.  
  384. CStr255& CStr255::operator += (const CString& str)
  385. {
  386.     InsertHelper (str, Length() + 1, kStr255Len);
  387.     return *this;
  388. } // CStr255::operator +=(CString)
  389.  
  390.  
  391. //----------------------------------------------------------------------------------------
  392. // CStr255::operator +=(char*):  Concatinate a string
  393. //----------------------------------------------------------------------------------------
  394.  
  395. CStr255& CStr255::operator += (const char* str)
  396. {
  397.     InsertHelper (str, Length() + 1, kStr255Len);
  398.     return *this;
  399. } // CStr255::operator +=(char*)
  400.  
  401.  
  402. //----------------------------------------------------------------------------------------
  403. // CStr255::operator +=(char):  Concatinate a single character
  404. //----------------------------------------------------------------------------------------
  405.  
  406. CStr255& CStr255::operator += (const char ch)
  407. {
  408.     if (++Length() <= kStr255Len)
  409.         fStr[Length()] = ch;
  410.     else
  411.     {
  412.         --Length();
  413. #if qDebugMsg
  414.         fprintf(stderr, "###CStr255::operator+=: Concatenation produces CStr255 overflow.\n");
  415. #endif
  416.     }
  417.     
  418.     return *this;
  419. } // CStr255::operator +=(char)
  420.  
  421.  
  422. //----------------------------------------------------------------------------------------
  423. // CStr255::operator =:
  424. //----------------------------------------------------------------------------------------
  425.  
  426. CStr255& CStr255::operator = (const char* str)
  427. {
  428.     if (str)
  429.     {
  430.         // Truncate the C CString to 255 bytes if necessary.
  431.         register size_t itsSize = strlen(str);
  432.         if (itsSize > kStr255Len)
  433.             Length() = kStr255Len;
  434.         else
  435.             Length() = itsSize;
  436.  
  437.         memcpy(&fStr[1], str, Length());
  438.     }
  439.     else
  440.         Length() = 0;
  441.     
  442.     return *this;
  443. } // CStr255::operator =
  444.  
  445.  
  446.  
  447. //========================================================================================
  448. // CLASS CStr63
  449. //========================================================================================
  450.  
  451.  
  452. //----------------------------------------------------------------------------------------
  453. // CStr63::CStr63(char*):
  454. //----------------------------------------------------------------------------------------
  455.  
  456. CStr63::CStr63(const char* str)
  457. {
  458.     // Truncate the C CString to 63 bytes if necessary.
  459.  
  460.     Length() = str == NULL ? 0 : strlen((const char*)str);
  461.     if (Length() > kStr63Len)
  462.         Length() = kStr63Len;
  463.     memcpy(&fStr[1], str, Length());
  464. } // CStr63::CStr63(char*)
  465.  
  466.  
  467. //----------------------------------------------------------------------------------------
  468. // CStr63::CStr63(long):
  469. //----------------------------------------------------------------------------------------
  470.  
  471. CStr63::CStr63(const long id)
  472. {
  473.     Length() = 4;
  474.     memcpy(&fStr[1], &id, Length());
  475. } // CStr63::CStr63(long)
  476.  
  477.  
  478. //----------------------------------------------------------------------------------------
  479. // CStr63::Copy:
  480. //----------------------------------------------------------------------------------------
  481.  
  482. CStr63 CStr63::Copy(short pos, short length)
  483. {
  484.     CStr63 newString;
  485.     
  486.     length = length > Length() - pos + kLengthByte ? Length() - pos + kLengthByte : length;
  487.     
  488.     if (length > 0)
  489.     {
  490.         memcpy(&newString.fStr[1], &fStr[pos], length);
  491.         newString.Length() = length;
  492.     }
  493.     else
  494.         newString = "";
  495.         
  496.     return newString;
  497.     
  498. } // CStr63::Copy
  499.  
  500.  
  501. //----------------------------------------------------------------------------------------
  502. // CStr63::operator +=(CString):  Concatinate a string
  503. //----------------------------------------------------------------------------------------
  504.  
  505. CStr63& CStr63::operator += (const CString& str)
  506. {
  507.     InsertHelper (str, Length() + 1, kStr63Len);
  508.     return *this;
  509. } // CStr63::operator +=(CString)
  510.  
  511.  
  512. //----------------------------------------------------------------------------------------
  513. // CStr63::operator +=(char*):  Concatinate a string
  514. //----------------------------------------------------------------------------------------
  515.  
  516. CStr63& CStr63::operator += (const char* str)
  517. {
  518.     InsertHelper (str, Length() + 1, kStr63Len);
  519.     return *this;
  520. } // CStr63::operator +=(char*)
  521.  
  522.  
  523. //----------------------------------------------------------------------------------------
  524. // CStr63::operator +=(char):  Concatinate a single character
  525. //----------------------------------------------------------------------------------------
  526.  
  527. CStr63& CStr63::operator += (const char ch)
  528. {
  529.     if (++Length() <= kStr63Len)
  530.         fStr[Length()] = ch;
  531.     else
  532.     {
  533.         --Length();
  534. #if qDebugMsg
  535.         fprintf(stderr, "###CStr63::operator+=: Concatenation produces CStr63 overflow.\n");
  536. #endif
  537.     }
  538.     
  539.     return *this;
  540. } // CStr63::operator +=(char)
  541.  
  542.  
  543.  
  544. //========================================================================================
  545. // CLASS CStr32
  546. //========================================================================================
  547.  
  548.  
  549. //----------------------------------------------------------------------------------------
  550. // CStr32::CStr32(char*):
  551. //----------------------------------------------------------------------------------------
  552.  
  553. CStr32::CStr32(const char* str)
  554. {
  555.     // Truncate the C CString to 32 bytes if necessary.
  556.  
  557.     Length() = str == NULL ? 0 : strlen((const char*)str);
  558.     if (Length() > kStr32Len)
  559.         Length() = kStr32Len;
  560.     memcpy(&fStr[1], str, Length());
  561. } // CStr32::CStr32(char*)
  562.  
  563.  
  564. //----------------------------------------------------------------------------------------
  565. // CStr32::CStr32(long):
  566. //----------------------------------------------------------------------------------------
  567.  
  568. CStr32::CStr32(const long id)
  569. {
  570.     Length() = 4;
  571.     memcpy(&fStr[1], &id, Length());
  572. } // CStr32::CStr32(long)
  573.  
  574.  
  575. //----------------------------------------------------------------------------------------
  576. // CStr32::Copy:
  577. //----------------------------------------------------------------------------------------
  578.  
  579. CStr32 CStr32::Copy(short pos, short length)
  580. {
  581.     CStr32 newString;
  582.     
  583.     length = length > Length() - pos + kLengthByte ? Length() - pos + kLengthByte : length;
  584.     
  585.     if (length > 0)
  586.     {
  587.         memcpy(&newString.fStr[1], &fStr[pos], length);
  588.         newString.Length() = length;
  589.     }
  590.     else
  591.         newString = "";
  592.         
  593.     return newString;
  594.  
  595. } // CStr32::Copy
  596.  
  597.  
  598.  
  599. //========================================================================================
  600. // CLASS CStr31
  601. //========================================================================================
  602.  
  603.  
  604. //----------------------------------------------------------------------------------------
  605. // CStr31::CStr31(char*):
  606. //----------------------------------------------------------------------------------------
  607.  
  608. CStr31::CStr31(const char* str)
  609. {
  610.     // Truncate the C CString to 31 bytes if necessary.
  611.  
  612.     Length() = str == NULL ? 0 : strlen((const char*)str);
  613.     if (Length() > kStr31Len)
  614.         Length() = kStr31Len;
  615.     memcpy(&fStr[1], str, Length());
  616. } // CStr31::CStr31(char*)
  617.  
  618.  
  619. //----------------------------------------------------------------------------------------
  620. // CStr31::CStr31(long):
  621. //----------------------------------------------------------------------------------------
  622.  
  623. CStr31::CStr31(const long id)
  624. {
  625.     Length() = 4;
  626.     memcpy(&fStr[1], &id, Length());
  627. } // CStr31::CStr31(long)
  628.  
  629.  
  630. //----------------------------------------------------------------------------------------
  631. // CStr31::Copy:
  632. //----------------------------------------------------------------------------------------
  633.  
  634. CStr31 CStr31::Copy(short pos, short length)
  635. {
  636.     CStr31 newString;
  637.     
  638.     length = length > Length() - pos + kLengthByte ? Length() - pos + kLengthByte : length;
  639.     
  640.     if (length > 0)
  641.     {
  642.         memcpy(&newString.fStr[1], &fStr[pos], length);
  643.         newString.Length() = length;
  644.     }
  645.     else
  646.         newString = "";
  647.         
  648.     return newString;
  649.  
  650. } // CStr31::Copy
  651.  
  652.  
  653. //----------------------------------------------------------------------------------------
  654. // CStr31::operator +=(CString):  Concatinate a string
  655. //----------------------------------------------------------------------------------------
  656.  
  657. CStr31& CStr31::operator += (const CString& str)
  658. {
  659.     InsertHelper (str, Length() + 1, kStr31Len);
  660.     return *this;
  661. } // CStr31::operator +=(CString)
  662.  
  663.  
  664. //----------------------------------------------------------------------------------------
  665. // CStr31::operator +=(char*):  Concatinate a string
  666. //----------------------------------------------------------------------------------------
  667.  
  668. CStr31& CStr31::operator += (const char* str)
  669. {
  670.     InsertHelper (str, Length() + 1, kStr31Len);
  671.     return *this;
  672. } // CStr31::operator +=(char*)
  673.  
  674.  
  675. //----------------------------------------------------------------------------------------
  676. // CStr31::operator +=(char):  Concatinate a single character
  677. //----------------------------------------------------------------------------------------
  678.  
  679. CStr31& CStr31::operator += (const char ch)
  680. {
  681.     if (++Length() <= kStr31Len)
  682.         fStr[Length()] = ch;
  683.     else
  684.     {
  685.         --Length();
  686. #if qDebugMsg
  687.         fprintf(stderr,"###CStr31::operator+=: Concatenation produces CStr31 overflow.\n");
  688. #endif
  689.     }
  690.     
  691.     return *this;
  692. } // CStr31::operator +=(char)
  693.